package com.spiro.gis.tiledownload;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Shaoping Huang
 * @Description:
 * @Date: 1/15/2018
 */
public class TileDownloadServer {

    public static void main(String[] args) throws IOException {

        if (args.length < 3) {
            System.out.println("Usage: TileDownloadServer <urlPattern> <baseTargetPath> <maxLevel> [recursive] [parallelism]");
            System.out.println("<urlPattern> is a pattern with 3 variable, z: map level, x: tile row index, y: tile col index.\n" +
                    "example: http://www.osm.org/{z}/{x}/{y}.png");
            System.exit(-1);
        }

        String urlPattern = args[0];
        String baseTargetPath = args[1];
        int maxLevel = Integer.valueOf(args[2]);

        boolean recursive = true;
        if (args.length > 3) {
            recursive = Boolean.valueOf(args[3]);
        }

        int parallelism = 0;
        if (args.length > 4) {
            parallelism = Integer.valueOf(args[4]);
        }

        System.out.println(">> urlPattern: " + urlPattern);
        System.out.println(">> baseTargetPath: " + baseTargetPath);
        System.out.println(">> maxLevel: " + maxLevel);
        System.out.println(">> recursive: " + recursive);
        System.out.println(">> parallelism: " + parallelism);

        BlockingQueue queue = new LinkedBlockingQueue(500000);
        TileDownloaderManager downloaderManager = new TileDownloaderManager();
        downloaderManager
                .setUrlPattern(urlPattern)
                .setBaseTargetDir(baseTargetPath)
                .setParallelism(parallelism)
                .setQueue(queue);
        TileCoordinateGenerator coordinateGenerator = new TileCoordinateGenerator(maxLevel, recursive, queue);
        Monitor.monitoring(coordinateGenerator, downloaderManager);

        downloaderManager.start();
        coordinateGenerator.generate();

        downloaderManager.endNotify();
        downloaderManager.join();
    }

    static class Monitor implements Runnable {

        public static void monitoring(TileCoordinateGenerator generator,
                                        TileDownloaderManager downloaderManager) {
            Thread thd = new Thread(new Monitor(generator, downloaderManager));
            thd.setDaemon(true);
            thd.start();
        }

        private final TileCoordinateGenerator generator;
        private final TileDownloaderManager downloaderManager;

        Monitor(TileCoordinateGenerator generator, TileDownloaderManager downloaderManager) {
            this.generator = generator;
            this.downloaderManager = downloaderManager;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                }

                long generateCount = this.generator.getGenerateCount();
                long downloadCount = this.downloaderManager.getDownloadCount();

                System.out.println("generateCount -> " + generateCount + ", downloadCount -> " + downloadCount);
            }
        }
    }
}
